package net.pimpas.web.jsf.components.ajax;

import javax.faces.context.FacesContext;
import javax.faces.el.MethodBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.FacesEvent;
import javax.faces.event.PhaseId;

import net.pimpas.logging.serviceprovider.LoggingServiceProvider;
import net.pimpas.logging.serviceprovider.LoggingServiceProviderFactoryImpl;
import net.pimpas.web.jsf.components.UIComponentPimpasBase;
import net.pimpas.web.jsf.util.ComponentInformation;

public abstract class UIAjax extends UIComponentPimpasBase {

	public static final String COMPONENT_TYPE			= ComponentInformation.COMPONENT_PREFIX_TYPE+".ajax";
	public static final String COMPONENT_FAMILY			= ComponentInformation.COMPONENT_PREFIX_FAMILY+".ajax";
	public static final String COMPONENT_RENDER_TYPE	= ComponentInformation.COMPONENT_PREFIX_RENDER+".ajax";
	
	public static final String AJAX_OBJECT_REQUEST_KEY	= "AJAX_REQUEST_OBJECT";
	
	private static final LoggingServiceProvider logger = 
		LoggingServiceProviderFactoryImpl.getLoggingServiceProvider(UIAjax.class);

	private String actionListener;
	private String event;
	private Boolean sendForm;
	private Boolean async;
	private Boolean immediate;
	private String control;
	

	private String render;
	
	public String getActionListener() {
		return actionListener;
	}
	public void setActionListener(String actionListener) {
		this.actionListener = actionListener;
	}
	public String getEvent() {
		return event;
	}
	public void setEvent(String event) {
		this.event = event;
	}
	
	@Override
	public Object saveState(FacesContext context) {
		Object[] ob = new Object[8];
		ob[0] = super.saveState(context);
		ob[1] = this.getEvent();
		ob[2] = this.getActionListener();
		ob[3] = this.getRender();
		ob[4] = this.getSendForm();
		ob[5] = this.getAsync();
		ob[6] = this.getImmediate();
		ob[7] = this.getControl();
		
		return ob;
	}
	
	@Override
	public void restoreState(FacesContext context, Object state) {
		Object[] ob = (Object[]) state;
		super.restoreState(context, ob[0]);
		this.setEvent((String) ob[1]);
		this.setActionListener((String) ob[2]);
		this.setRender((String) ob[3]);
		this.setSendForm((Boolean) ob[4]);
		this.setAsync((Boolean) ob[5]);
		this.setImmediate((Boolean) ob[6]);
		this.setControl((String) ob[7]);
	}
	
	@Override
	public void queueEvent(FacesEvent event) {
		event.setPhaseId(PhaseId.INVOKE_APPLICATION);
		super.queueEvent(event);
	}
	
	@Override
	public boolean getRendersChildren() {
		return false;
	}
	
	@Override
	public void broadcast(FacesEvent event) throws AbortProcessingException {
		logger.info("[UIAJAX]: Executing ActionListener, Event => "+this.getEvent());
		MethodBinding mb = FacesContext.getCurrentInstance().getApplication().createMethodBinding(this.getActionListener(), new Class[]{ActionEvent.class});
		mb.invoke(FacesContext.getCurrentInstance(), new Object[]{new ActionEvent(this)});
		logger.info("[UIAJAX]: ActionListener executed!");
	}
	public String getRender() {
		return render;
	}
	public void setRender(String render) {
		this.render = render;
	}
	public Boolean getSendForm() {
		return sendForm;
	}
	public void setSendForm(Boolean sendForm) {
		this.sendForm = sendForm;
	}
	public Boolean getAsync() {
		return async;
	}
	public void setAsync(Boolean async) {
		this.async = async;
	}
	public Boolean getImmediate() {
		return immediate;
	}
	public void setImmediate(Boolean immediate) {
		this.immediate = immediate;
	}
	public String getControl() {
		return control;
	}
	public void setControl(String control) {
		this.control = control;
	}
}